using System;
using System.Collections.Generic;
using Kayac;
using Unity.Burst.Intrinsics;
using Unity.VisualScripting;
using UnityEngine;

public class Enemy : MonoBehaviour, IEnemy, IEnemyObject
{
	public float force = 1f;
	public enum DamageType
	{
		Deflect = 0,
		Impale = 1,
		Cut = 2,
		Kill = 3,
		Impact = 4,
		Unknown = 5
	}

	[Serializable]
	private class Settings
	{
		public float moveSpeed;

		public float moveSpeedOnLast;

		public float forceRelaxAngularVelocity;

		public float deathThreashold;

		public float punchProbability;

		public float punchDistribution;

		public float punchStrength;

		public float shockFactor;

		public float shockRecovery;

		public float irisScaleFactor;

		public float eyeShockThreshold;

		public float landNormalUpdate;

		public float torqueRadius;

		public float hipsAngularDrag;

		public PidSettings headPid;

		public PidSettings hipsPid;

		public PidSettings upperLegPid;

		public PidSettings lowerLegPid;

		public PidSettings movePid;

		public PidSettings shieldArmPid;

		public Material deathMaterial;

		public bool optional;

		public bool inView;

		public bool zoomedOnLast;
	}

	[SerializeField]
	private Settings settings;
	[SerializeField]
	private EnemyPart head;
	[SerializeField]
	private EnemyPart hips;
	[SerializeField]
	bool isLegForce = true;

	[SerializeField]
	private EnemyPart upperLegL;
	[SerializeField]
	private EnemyPart upperLegR;
	[SerializeField]
	private EnemyPart lowerLegL;
	[SerializeField]
	private EnemyPart lowerLegR;
	[SerializeField]
	bool isArmForce = true;
	[SerializeField]
	private EnemyPart upperArmL;
	[SerializeField]
	private EnemyPart upperArmR;
	[SerializeField]
	private EnemyPart lowerArmL;
	[SerializeField]
	private EnemyPart lowerArmR;

	[SerializeField]
	private Eyes eyes;

	[SerializeField]
	private GameObject enabledOnDeath;

	[SerializeField]
	private Cannon cannon;

	private PidControllerRotation headPid;

	private PidControllerRotation hipsPid;

	private PidControllerRotation upperLegLPid;

	private PidControllerRotation upperLegRPid;

	private PidControllerRotation lowerLegLPid;

	private PidControllerRotation lowerLegRPid;

	private PidControllerRotation shieldArmPid;

	private PidController3 movePidL;

	private PidController3 movePidR;

	private bool killedPlayer;

	private float initialSurfaceAreaSum;

	private float currentSurfaceAreaSum;

	private Vector3 integratedHipsAngularVelocity;

	private float integratedHipsVelocityY;

	private float shock;

	private Vector3 landNormal;

	private Level level;

	private bool initializeEnabledOnDeathCalled;

	private float punchLTimer;

	private float punchRTimer;

	private float steepestDescentAlpha;

	private Vector3 lastPlayerHeadPosition;

	private Vector3 lastGunDirectionGoal;

	private bool hasHead;

	private bool inEmergencyStop;

	public bool Active
	{
		get; private set;
	}
	public bool Alive { get; private set; }

	public bool Optional => false;

	public bool InView => false;

	public bool ZoomedOnLast => false;

	public Material DeathMaterial
	{
		get
		{
			return settings.deathMaterial;
		}
	}

	public Vector3 CenterBodyPosition => default(Vector3);

	public Vector3 Position
	{
		get
		{
			return hips.transform.position;
		}
		private set
		{

		}
	}

	public float ApproxRadius { get; private set; }

	public Level.Settings LevelSettings => null;
	float TimeInterval = 0.1f;
	float Timer = 0f;
	public Action<IEnemy> OnKilled;
	public void ManualStart(Level level, Dictionary<string, Material> materialSet)
	{
		Active = true;
		if (head != null)
			Alive = true;
		else
			Alive = false;
		Position = transform.position;
		this.level = level;
		head?.ManualStart(this);
		hips?.ManualStart(this);
		upperLegL?.ManualStart(this);
		upperLegR?.ManualStart(this);
		lowerLegL?.ManualStart(this);
		lowerLegR?.ManualStart(this);
		upperArmL?.ManualStart(this);
		upperArmR?.ManualStart(this);
		lowerArmL?.ManualStart(this);
		lowerArmR?.ManualStart(this);
		// eyes?.ManualStart();
	}

	public void InitializeEnabledOnDeath()
	{
	}
	Vector3 targetVector;
	public void ManualFixedUpdate(float deltaTime, Vector3 playerHeadPosition, bool isLast)
	{
		if (!Alive)
			return;
		head?.ManualFixedUpdate(deltaTime);
		hips?.ManualFixedUpdate(deltaTime);
		upperLegL?.ManualFixedUpdate(deltaTime);
		upperLegR?.ManualFixedUpdate(deltaTime);
		lowerLegL?.ManualFixedUpdate(deltaTime);
		lowerLegR?.ManualFixedUpdate(deltaTime);
		upperArmL?.ManualFixedUpdate(deltaTime);
		upperArmR?.ManualFixedUpdate(deltaTime);
		lowerArmL?.ManualFixedUpdate(deltaTime);
		lowerArmR?.ManualFixedUpdate(deltaTime);
		Timer += Time.fixedDeltaTime;
		if (Timer >= TimeInterval)
		{
			TimeInterval = UnityEngine.Random.Range(0.1f, 0.5f); // 随机时间间隔
			Timer = 0f;
			if (isArmForce)
			{
				targetVector = new Vector3(UnityEngine.Random.Range(-1f, 1f), UnityEngine.Random.Range(-1f, 1f), UnityEngine.Random.Range(-1f, 1f));
				MoveEnemyPart(playerHeadPosition, targetVector, lowerArmL);
				targetVector = new Vector3(UnityEngine.Random.Range(-1f, 1f), UnityEngine.Random.Range(-1f, 1f), UnityEngine.Random.Range(-1f, 1f));
				MoveEnemyPart(playerHeadPosition, targetVector, lowerArmR);
				targetVector = new Vector3(UnityEngine.Random.Range(-1f, 1f), UnityEngine.Random.Range(-1f, 1f), UnityEngine.Random.Range(-1f, 1f));
				MoveEnemyPart(playerHeadPosition, targetVector, upperArmL);
				targetVector = new Vector3(UnityEngine.Random.Range(-1f, 1f), UnityEngine.Random.Range(-1f, 1f), UnityEngine.Random.Range(-1f, 1f));
				MoveEnemyPart(playerHeadPosition, targetVector, upperArmR);
			}
			if (isLegForce)
			{
				targetVector = new Vector3(UnityEngine.Random.Range(-1f, 1f), UnityEngine.Random.Range(-1f, 1f), UnityEngine.Random.Range(-1f, 1f));
				MoveEnemyPart(playerHeadPosition, targetVector, lowerLegL);
				targetVector = new Vector3(UnityEngine.Random.Range(-1f, 1f), UnityEngine.Random.Range(-1f, 1f), UnityEngine.Random.Range(-1f, 1f));
				MoveEnemyPart(playerHeadPosition, targetVector, lowerLegR);
				targetVector = new Vector3(UnityEngine.Random.Range(-1f, 1f), UnityEngine.Random.Range(-1f, 1f), UnityEngine.Random.Range(-1f, 1f));
				MoveEnemyPart(playerHeadPosition, targetVector, upperLegL);
				targetVector = new Vector3(UnityEngine.Random.Range(-1f, 1f), UnityEngine.Random.Range(-1f, 1f), UnityEngine.Random.Range(-1f, 1f));
				MoveEnemyPart(playerHeadPosition, targetVector, upperLegR);
			}
		}

	}
	public void MoveEnemyPart(Vector3 playerHeadPosition, Vector3 targetVector, EnemyPart enemyPart)
	{
		if (enemyPart == null) return;

		Vector3 Forward = (playerHeadPosition - enemyPart.transform.position).normalized;
		Vector3 targetVectorForward = targetVector.normalized;
		float force = (Vector3.Dot(Forward, targetVectorForward) > 0 ? 1f : 0.2f) * this.force;
		enemyPart.AddForceAtPosition(targetVector * force, enemyPart.transform.position, ForceMode.Impulse);
	}
	public void ManualUpdate(float deltaTime)
	{
		if (!Alive)
			return;
		head?.ManualUpdate(deltaTime);
		hips?.ManualUpdate(deltaTime);
		upperLegL?.ManualUpdate(deltaTime);
		upperLegR?.ManualUpdate(deltaTime);
		lowerLegL?.ManualUpdate(deltaTime);
		lowerLegR?.ManualUpdate(deltaTime);
		upperArmL?.ManualUpdate(deltaTime);
		upperArmR?.ManualUpdate(deltaTime);
		lowerArmL?.ManualUpdate(deltaTime);
		lowerArmR?.ManualUpdate(deltaTime);
		eyes?.ManualUpdate(deltaTime);
		if (hips.transform.position.y < -5f)
		{
			Alive = false;
		}
		if (head != null)
		{
			Quaternion targetRot = Quaternion.LookRotation(Main.Instance.player.transform.position - head.transform.position, Vector3.up);
			head.GetComponent<Rigidbody>().MoveRotation(Quaternion.Slerp(head.GetComponent<Rigidbody>().rotation, targetRot, deltaTime * 10f));
		}
		if (Vector3.Distance(hips.transform.position, Main.Instance.player.transform.position) < 2f)
		{
			TryPunch();
		}
	}
	void TryPunch()
	{
		// 1. 概率检查
		if (UnityEngine.Random.value > settings.punchProbability) return;

		// 2. 选择左右拳
		bool useLeft = UnityEngine.Random.value < settings.punchDistribution;
		EnemyPart arm;
		if (upperArmL != null && upperArmR != null)
		{
			arm = useLeft ? upperArmL : upperArmR;
		}
		else
		{
			arm = useLeft ? lowerArmL : lowerArmR;
		}
		// 3. 计算拳击方向 (简化示例)
		Vector3 playerDir = (Main.Instance.player.transform.position - arm.transform.position).normalized;

		// 4. 施加拳击力
		float strength = settings.punchStrength;
		arm.AddForce(playerDir * strength, ForceMode.Impulse);
		level.Player.Die(playerDir * strength);
	}
	public void OnKillPlayer()
	{
	}

	public void OnLand(Vector3 normal, bool entering)
	{
	}

	public void Damage(float damage, DamageType type, EnemyPart part, float shockMultiplier)
	{
	}

	public void CollectPartPoints(List<Vector3> points)
	{

	}

	public bool HasLeg()
	{
		return false;
	}
	public void ForceClear()
	{
		hips.GetComponent<Rigidbody>().isKinematic = true;
	}
	public void ResetForce()
	{
		hips.GetComponent<Rigidbody>().isKinematic = false;
	}
	public void OnDestroyPart(EnemyPart part)
	{
		if (part == null)
			return;

		if (part == head)
		{
			head = null;
			hasHead = false;
		}
		else if (part == upperLegL)
		{
			upperLegL = null;
		}
		else if (part == upperLegR)
		{
			upperLegR = null;
		}
		else if (part == lowerLegL)
		{
			lowerLegL = null;
		}
		else if (part == lowerLegR)
		{
			lowerLegR = null;
		}
		else if (part == upperArmL)
		{
			upperArmL = null;
		}
		else if (part == upperArmR)
		{
			upperArmR = null;
		}
		else if (part == lowerArmL)
		{
			lowerArmL = null;
		}
		else if (part == lowerArmR)
		{
			lowerArmR = null;
		}
		if (part == hips)
		{
			Die();
		}
	}

	public void OnFireCannonBall(CannonBall cannonBall)
	{
	}

	private float CalcFireMissDistance(Vector3 fireDirection)
	{
		return 0f;
	}

	private void Shock(float amount)
	{
	}

	private float CalcPunchTimer()
	{
		return 0f;
	}

	private static void Rotate(EnemyPart child, EnemyPart parent, Vector3 torque, float torqueRadius)
	{
		// float distanceFactor = Mathf.Clamp01(Vector3.Distance(child.position, parent.position) / torqueRadius);
		// Vector3 adjustedTorque = torque * (1f - distanceFactor);

		// // 应用到子部位的刚体
		// if (child.Rigidbody != null)
		// {
		// 	child.Rigidbody.AddTorque(adjustedTorque, ForceMode.Impulse);
		// }
	}

	private void UpdateShock(float deltaTime)
	{
	}

	private void Die()
	{
		Alive = false;
	}

	private void SetDampings(float damping)
	{
	}
}
